<?php declare(strict_types=1);

namespace App\Bac\Handler\RBAC;

use App\Helper\RespHelper;
use Hyperf\DbConnection\Db;
use App\Bac\Model\RBAC\Roles;
use App\Exception\BusinessException;
use DbModels\RBAC\RolePermission;
use Hyperf\Di\Annotation\Inject;
use Psr\Log\LoggerInterface;

class RoleHandler
{

    use CacheManager;

    #[Inject]
    protected Roles $model;
    protected LoggerInterface $logHelper;

    public function __construct()
    {
        $this->logHelper = getLogger('http-back');
    }

    public function getList(array $queries): array
    {
        $query = $this->model->with('permissionid');
        [$page, $size] = getPageFormParams($queries);
        $title = $queries['title'] ?? null;
        if ($title) {
            $query->where('display_name', 'like', '%' . $title . '%');
        }
        $total = (clone $query)->count();
        $query->offset(($page - 1) * $size)->limit($size);
        $rows = $query->get()->toArray();
        $rows && $rows = $this->formatRows($rows);
        return compact("rows", "total");
    }

    private function formatRows($rows): array
    {
        if (!$rows) return [];
        foreach ($rows as &$v) {
            $v['permissionIds'] = null;
            if ($v['permissionid']) {
                $v['permissionIds'] = array_column($v['permissionid'], 'pms_id');
            }
            unset($v['permissionid']);
        }
        return $rows;
    }

    public function addRoles(array $data): bool
    {
        $data['created_at'] = date('Y-m-d H:i:s', time());
        if ($this->model->where('name', $data['name'])->exists())
            throw new BusinessException(RespHelper::CODE_FAIL, "标识已经存在");

        $permissions = $data['permission'];
        unset($data['permission']);
        Db::beginTransaction();
        try {
            $id = $this->model->insertGetId($data);
            //角色和权限关联
            $rolesPermiss = [];
            $today = date('Y-m-d H:i:s', time());
            foreach ($permissions as $v) {
                $rolesPermiss[] = ['role_id' => $id, 'pms_id' => $v, 'created_at' => $today];
            }
            RolePermission::insert($rolesPermiss);
            Db::commit();
            return true;
        } catch (\Throwable $e) {
            $this->logHelper->debug(getErrStr($e));
            Db::rollBack();
            return false;
        }
    }

    public function editRoles(int $id, array $data): bool
    {
        $info = $this->model->find($id);
        if (!$info)
            throw new BusinessException(RespHelper::CODE_NOTFOUND, "角色不存在");
        if (isset($data['name']) && !empty(trim($data['name']))) {
            $info->name = $data['name'];
        }
        if (isset($data['display_name']) && !empty(trim($data['display_name']))) {
            $info->display_name = $data['display_name'];
        }
        if (isset($data['state']) && !empty(trim($data['state']))) {
            $info->state = $data['state'];
        }
        $permissions = $data['permission'];
        unset($data['permission']);
        Db::beginTransaction();
        try {
            $info->save();
            $rolesPerIds = RolePermission::where('role_id', $id)->pluck('pms_id')->toArray();
            //新增的
            $addPerIds = array_diff($permissions, $rolesPerIds);
            $today = date('Y-m-d H:i:s', time());
            $rolesPermiss = [];
            if ($addPerIds) {
                foreach ($addPerIds as $v) {
                    $rolesPermiss[] = ['role_id' => $id, 'pms_id' => $v, 'created_at' => $today];
                }
            }
            if ($rolesPermiss)
                RolePermission::insert($rolesPermiss);
            //删除的
            $delPerIds = array_diff($rolesPerIds, $permissions);
            if ($delPerIds) {
                RolePermission::where('role_id', $id)->whereIn('pms_id', $delPerIds)->delete();
            }
            // 清楚相关用户权限缓存，若不清楚的话会导致更新不生效
            $this->clearRoleRelationCache([$info->id]);
            Db::commit();
            return true;
        } catch (\Throwable $e) {
            $this->logHelper->debug(getErrStr($e));
            Db::rollBack();
            return false;
        }
    }

    /**
     * 删除权限
     * @param $ids
     * @return int
     */
    public function delRoles($ids): int
    {
        $deleted = $this->model->destroy($ids);
        if ($deleted) {
            $clearParams = is_array($ids) ? $ids : [$ids];
            $this->clearRoleRelationCache($clearParams);
        }
        return $deleted;
    }


}
